package bo;

import dao.AcaoDAO;
import dao.UsuarioAcaoDAO;
import dao.UsuarioDAO;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import model.Acao;
import model.Usuario;
import model.UsuarioAcao;
import org.hibernate.criterion.Restrictions;
import util.ConsUtil;
import util.CustomException;

@Path("services/usuario")
public class UsuarioBO extends AbstractBO {

    private UsuarioDAO usuarioDAO = new UsuarioDAO();
    private AcaoDAO acaoDAO = new AcaoDAO();
    private UsuarioAcaoDAO usuarioAcaoDAO = new UsuarioAcaoDAO();

    @GET
    @Path("{email}/{senha}")
    @Produces({"application/xml", "application/json"})
    public Usuario login(@PathParam("email") String email, @PathParam("senha") String senha) throws CustomException {
        Usuario usuarioLogado = null;
        try {
            beginTransaction();
            if ((email.equals(ConsUtil.MASTER_LOGIN)) && (senha.equals(ConsUtil.MASTER_PASSWORD))) {
                usuarioLogado = new Usuario(0, "Master", ConsUtil.MASTER_LOGIN, ConsUtil.MASTER_PASSWORD);
            } else {
                usuarioLogado = usuarioDAO.login(getSession(), email, senha);
            }
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return usuarioLogado;
    }

    public Usuario selecionarPorEmail(String email) throws CustomException {
        Usuario usuario = null;
        try {
            beginTransaction();
            usuario = usuarioDAO.selecionarRegistroPorCriterio(getSession(), Restrictions.eq("usuEmail", email));
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return usuario;
    }

    public List<Acao> selecionarPermissao(Usuario usuario) throws CustomException {
        List<Acao> result = new ArrayList();
        try {
            beginTransaction();
            result = acaoDAO.selecionarPermissao(getSession(), usuario);
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return result;
    }

    public List<Usuario> selecionarTodos() throws CustomException {
        List<Usuario> usuarioList = new ArrayList();
        try {
            beginTransaction();
            usuarioList = usuarioDAO.selecionarListaPorCriterio(getSession());
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return usuarioList;
    }

    public Usuario selecionarPorId(Long usuCodigo) throws CustomException {
        Usuario usuario = null;
        try {
            beginTransaction();
            usuario = usuarioDAO.selecionarPorId(getSession(), usuCodigo);
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return usuario;
    }

    public List<UsuarioAcao> selecionarAcoesPorUsuario(Usuario usuario) throws CustomException {
        List<UsuarioAcao> usuarioAcaoList = new ArrayList();
        try {
            beginTransaction();
            usuarioAcaoList = usuarioAcaoDAO.selecionarPorUsuario(getSession(), usuario);
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return usuarioAcaoList;
    }

    public List<UsuarioAcao> selecionarAcoesPorNovoUsuario(Usuario usuario) throws CustomException {
        List<UsuarioAcao> usuarioAcaoList = new ArrayList();
        try {
            beginTransaction();
            usuarioAcaoList = usuarioAcaoDAO.selecionarPorNovoUsuario(getSession(), usuario);
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
        return usuarioAcaoList;
    }

    public void salvar(Usuario usuario) throws CustomException {
        try {
            beginTransaction();
            if (usuario.getUsuCodigo() == 0) {
                usuario.setUsuCodigo(usuarioDAO.selecionarProximoId(getSession()));
            }
            usuarioDAO.salvar(getSession(), usuario);
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
    }

    public void salvar(Usuario usuario, List<UsuarioAcao> usuarioAcoes) throws CustomException {
        try {
            beginTransaction();
            if (usuario.getUsuCodigo() == 0) {
                // Obtendo o novo valor da sequence
                usuario.setUsuCodigo(usuarioDAO.selecionarProximoId(getSession()));
            } else {
                // Excluindo as permissões antigas
                usuarioDAO.excluirPermissoes(getSession(), usuario);
            }

            // Salvando o usuário
            usuarioDAO.salvar(getSession(), usuario);
            // Salvando as permissões novas
            for (UsuarioAcao usuarioAcao : usuarioAcoes) {
                usuarioAcao.setUsuario(usuario);
                usuarioAcao.setUsaCodigo(usuarioAcaoDAO.selecionarProximoId(getSession()));
                usuarioAcaoDAO.salvar(getSession(), usuarioAcao);
            }
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
    }

    public void excluir(Usuario usuario) throws CustomException {
        try {
            beginTransaction();
            // Excluindo permissões
            usuarioDAO.excluirPermissoes(getSession(), usuario);
            // Excluindo usuário
            usuarioDAO.excluir(getSession(), usuario);
            commitTransaction();
        } catch (CustomException e) {
            rollbackTransaction();
            throw e;
        }
    }
}
